import { API_CONFIG } from '@/config/api'

type RequestInterceptor = (config: RequestConfig) => RequestConfig | Promise<RequestConfig>
type ResponseInterceptor<T = any> = (response: T) => T | Promise<T>

interface Interceptors {
    request: RequestInterceptor[]
    response: ResponseInterceptor[]
}

const interceptors: Interceptors = {
    request: [
        // 自动携带Token
        config => {
            const token = uni.getStorageSync('ACCESS_TOKEN')
            if (token) {
                config.header = {
                    ...config.header,
                    Authorization: `Bearer ${token}`
                }
            }
            return config
        }
    ],
    response: []
}

export const BASE_URL = API_CONFIG.BASE_URL

interface RequestConfig {
    url: string
    method?: 'GET' | 'POST' | 'PUT' | 'DELETE'
    data?: any
    header?: Record<string, string>
    timeout?: number
}

const createRequest = async (config: RequestConfig) => {
    return new Promise<any>(async (resolve, reject) => {
        // 应用请求拦截器
        let processedConfig = config
        for (const interceptor of interceptors.request) {
            processedConfig = await interceptor(processedConfig)
        }

        const { url, method = 'GET', data = {}, header = {}, timeout = 10000 } = processedConfig

        uni.request({
            timeout,
            url: BASE_URL + url,
            method,
            data,
            header: {
                'Content-Type': 'application/json',
                ...header
            },
            success: async res => {
                try {
                    // 应用响应拦截器
                    let processedResponse = res.data
                    for (const interceptor of interceptors.response) {
                        processedResponse = await interceptor(processedResponse)
                    }

                    if (res.statusCode >= 200 && res.statusCode < 300) {
                        resolve(processedResponse)
                    } else {
                        handleError(res)
                        reject(res)
                    }
                } catch (error) {
                    handleError(error)
                    reject(error)
                }
            },
            fail: err => {
                handleError(err)
                reject(err)
            }
        })
    })
}

const handleError = (error: any) => {
    const errorMap: Record<number, string> = {
        400: '请求参数错误',
        401: '身份验证失败，请重新登录',
        403: '没有操作权限',
        404: '资源不存在',
        408: '请求超时',
        429: '请求过于频繁',
        500: '服务器内部错误',
        502: '网关错误',
        503: '服务不可用',
        504: '网关超时'
    }

    // 统一错误格式
    const errorMessage = {
        code: error.statusCode || -1,
        message: errorMap[error.statusCode] || '未知错误',
        data: error.data || null,
        original: error
    }

    // 显示Toast提示
    uni.showToast({
        title: errorMessage.message,
        icon: 'none',
        duration: 2000
    })

    return Promise.reject(errorMessage)
}

export const http = {
    get: <T = any>(url: string, params?: object) => createRequest({ url, method: 'GET', data: params }) as Promise<T>,
    post: <T = any>(url: string, data?: object) => createRequest({ url, method: 'POST', data }) as Promise<T>
}
